package com.lunz.securityproject.controller;

import com.lunz.securityproject.entity.domain.SysUser;
import com.lunz.securityproject.entity.vo.RegisterUser;
import com.lunz.securityproject.entity.vo.UpdatePassword;
import com.lunz.securityproject.module.JsonResult;
import com.lunz.securityproject.module.ResultCode;
import com.lunz.securityproject.module.ResultTool;
import com.lunz.securityproject.service.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.session.SessionInformation;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.userdetails.User;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @Author 施瑞贤
 * @email shiruixian@zhongruigroup.com
 * @date 2021/11/5 17:04
 */
@Api(tags = "用户管理")
@RequestMapping("user")
@RestController
@CrossOrigin
public class UserController {
    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SessionRegistry sessionRegistry;

    @ApiOperation("获取用户信息")
    @GetMapping("/getUser")
    public JsonResult getUser(){
        SysUser user = sysUserService.selectByName("lisi");
        return ResultTool.success(user);
    }

    @ApiOperation("用户注册")
    @PostMapping("/register")
    public JsonResult register(RegisterUser user) throws Exception{
        //因为验证需要表单格式的数据而不是JSON数据，所以不需要加@RequestBody注解
        if(user == null){
            return ResultTool.fail(ResultCode.PARAM_IS_BLANK);
        }else{
            //开始注册
            int result = sysUserService.insert(user);
            if(result > 0){
                return ResultTool.success();
            }else if(result == 0){
                return ResultTool.fail(ResultCode.USER_ACCOUNT_ALREADY_EXIST);
            }else{
                return ResultTool.fail();
            }
        }
    }

    @ApiOperation("修改密码")
    @PostMapping("/updatePassword")
    public JsonResult updatePassword(Authentication authentication, UpdatePassword updatePassword){
        String account = authentication.getName();
        int result = sysUserService.updatePassword(account,updatePassword);
        if(result == -1){
            return ResultTool.fail(ResultCode.USER_CREDENTIALS_ERROR);
        }
        if(result > 0){
            //修改成功，踢出用户，让用户重新登录
            kickOutUser(account);
            return ResultTool.success();
        }
        return ResultTool.fail();
    }

    @ApiOperation("删除账号")
    @PostMapping("/deleteUser")
    public JsonResult deleteUser(Authentication authentication){
        String account = authentication.getName();
        if(account == null){
            return ResultTool.fail(ResultCode.PARAM_IS_BLANK);
        }
        int result = sysUserService.deleteUser(account);
        if(result > 0){
            //注销成功，退回到未登录状态
            kickOutUser(account);
            return ResultTool.success();
        }
        return ResultTool.fail();
    }


    /**
     * 踢出指定用户
     * @param account
     */
    private void kickOutUser(String account){
        //获取session中所有用户信息
        List<Object> users = sessionRegistry.getAllPrincipals();
        for(Object principal : users ){
            //判断principal是否为 User类
            if(principal instanceof User){
                //获取用户名
                String principalName = ((User)principal).getUsername();
                //与传入的用户名比对
                if(principalName.equals(account)){
                    //获取session，获取该principal上的所有session
                    List<SessionInformation> sessionInformations = sessionRegistry.getAllSessions(principal, false);
                    if(sessionInformations != null && sessionInformations.size() > 0){
                        for(SessionInformation sessionInformation : sessionInformations){
                            //将session改成过期
                            sessionInformation.expireNow();
                        }
                    }
                }
            }
        }
    }
}
